﻿using System.Collections.Generic;
using System.IO;

//

namespace Chimp.Core
{
    public class ChimpFX
    {
        internal static FileStream _fs;
        internal static TextWriter _w;
        public static List<ChimpFXNode> NodeTypes = new List<ChimpFXNode>();

        public static List<string> MainCode = new List<string>();
        public static List<string> PreCode = new List<string>();
        public static List<string> PostCode = new List<string>();
        private static readonly List<ChimpFXNode> WroteNodes = new List<ChimpFXNode>();

        public static void ConvertGraphToShader(ChimpFXNode m, string path)
        {
            _fs = new FileStream(path, FileMode.Create, FileAccess.Write);
            _w = new StreamWriter(_fs);
            WriteShader(m);
            WriteFile();
            _w.Flush();
            _fs.Flush();
            _fs.Close();
            _w = null;
            _fs = null;
        }

        internal static void WriteFile()
        {
            foreach (string c in PreCode)
            {
                _w.WriteLine(c);
            }
            foreach (string c in MainCode)
            {
                _w.WriteLine(c);
            }
            foreach (string c in PostCode)
            {
                _w.WriteLine(c);
            }
        }

        internal static void WriteShader(ChimpFXNode m)
        {
            MainCode.Clear();
            PreCode.Clear();
            PostCode.Clear();

            InitCode(
                @"
	uniform vec4 MaterialDiffuseColor;
	uniform vec4 MaterialSpecularColor;
	uniform float MaterialSpecularPower;
	uniform vec4 LightDiffuseColor;
	uniform vec4 LightAmbientColor;
	uniform vec3 LightPosition;
	uniform float LightRange;
	
	varying vec3 normal,lightDir,halfVector;
	varying vec3 position;
	
	uniform int DiffuseMapping;
	uniform int NormalMapping;
	uniform int MaterialLightType;		
	uniform int MaterialLightingBit;

	varying vec3 tangent,binormal;	
    

            
");

            WroteNodes.Clear();

            Func("main");


            Code("vec4 fDif;");
            ZeroVec4("fDif");


            WriteConnection(m.GetIn("Diffuse").To);

            Code("fDif = " + m.GetIn("Diffuse").To.Owner.PropNodeName + "_" + m.GetIn("Diffuse").To.ID + ";");


            Code("gl_FragColor = fDif;");
            Code("gl_FragColor.a =1.0;");

            Close();
        }

        internal static void ZeroVec4(string id)
        {
            Code(id + ".x=0.0;");
            Code(id + ".y=0.0;");
            Code(id + ".z=0.0;");
            Code(id + ".w=0.0;");
        }

        internal static void WriteConnection(ChimpEffectPar to)
        {
            ChimpFXNode n = to.Owner;


            if (WroteNodes.Contains(n))
            {
            }
            else
            {
                WroteNodes.Add(n);
                foreach (ChimpEffectPar bn in n.In)
                {
                    WriteConnection(bn.To);
                }

                n.ProduceSegment(n.In);
            }
        }

        internal static void Code(string code)
        {
            //_w.WriteLine(code);
            MainCode.Add(code);
        }

        public static void InitCode(string code)
        {
            PreCode.Add(code);
        }

        internal static void Func(string name)
        {
            Code("void " + name + "(){");
        }

        internal static void Close()
        {
            Code("}");
        }

        public static void RegisterNodeType(ChimpFXNode node)
        {
            NodeTypes.Add(node);
        }

        public static ChimpFXNode GetNodeType(string id)
        {
            foreach (ChimpFXNode n in NodeTypes)
            {
                if (n.ID == id) return n;
            }
            return null;
        }

        public static void InitXenoFX()
        {
            RegisterNodeType(new xConstantFloat());
            RegisterNodeType(new xOperatorMultiply());
            RegisterNodeType(new xTexture2DNode());
            RegisterNodeType(new xReadTexture2DNode());
            ;
        }
    }
}